use std::cell::{Ref, RefCell, RefMut};
use std::ops::Deref;
use std::rc::Rc;
use std::thread::sleep;
use crate::alg::bd_link_List::node::Node;

///实现一个简单的双端链表
// DbLinkList
type NodePtr<T> = Option<Rc<RefCell<Node<T>>>>;
pub struct DbLinkList<T> {
    head: NodePtr<T>,
    tail: NodePtr<T>,
}

impl<T> DbLinkList<T> {
    // 初始化
    pub fn new() -> Self {
        DbLinkList {
            head: None,
            tail: None,
        }
    }
    //查看头尾
    pub fn peek_head(&self) -> Option<Ref<T>> {
        self.head
            .as_ref()
            .map(|ref_node| Ref::map(ref_node.borrow(), |node| &node.element))
    }

    pub fn peek_tail(&self) -> Option<Ref<T>> {
        self.tail
            .as_ref()
            .map(|ref_node| Ref::map(ref_node.borrow(), |node| &node.element))
    }

    //插入头部
    pub fn push_head(&mut self, element: T) {
        let new_node = Node::new(element);
        match self.head.take() {
            None => {
                self.head = Some(new_node.clone());
                self.tail = Some(new_node);
            }
            Some(old_head) => {
                old_head.borrow_mut().prev = Some(new_node.clone());
                new_node.borrow_mut().next = Some(old_head);
                self.head = Some(new_node);
            }
        }
    }
    //插入尾部
    pub fn push_tail(&mut self, element: T) {
        let new_node = Node::new(element);
        match self.tail.take() {
            None => {
                self.head = Some(new_node.clone());
                self.tail = Some(new_node);
            }
            Some(old_head) => {
                old_head.borrow_mut().next = Some(new_node.clone());
                new_node.borrow_mut().prev = Some(old_head);
                self.tail = Some(new_node);
            }
        }
    }
    //取出头部
    pub fn pop_head(&mut self) -> Option<T> {
        self.head.take().map(|old_head| {
            match old_head.borrow_mut().next.take() {
                None => {
                    self.tail.take();
                }
                Some(next) => {
                    // 使用=None / take / replace都可以 None性能更好
                    next.borrow_mut().prev = None;
                    self.head = Some(next);
                }
            };
            Rc::try_unwrap(old_head).ok().unwrap().into_inner().element
        })
    }
    //取出尾部
    pub fn pop_tail(&mut self) -> Option<T> {
        self.tail.take().map(|old_tail| {
            match old_tail.borrow_mut().prev.take() {
                None => {
                    self.head.take();
                }
                Some(prev) => {
                    prev.borrow_mut().next = None;
                    self.head = Some(prev);
                }
            };
            Rc::try_unwrap(old_tail).ok().unwrap().into_inner().element
        })
    }

    //intoIter
    pub fn into_iter(self) -> IntoIter<T> {
        IntoIter(self)
    }
    //iter
    pub fn iter(&self) -> Iter<T> {
        Iter(self.head.as_ref().map(|head| head.borrow()))
    }

    //iter_mut
    // pub fn iter_mut(self) -> IterMut<T> {
    //     IterMut(self)
    // }
}

mod node {
    use super::NodePtr;
    use std::cell::RefCell;
    use std::rc::Rc;
    pub(super) struct Node<T> {
        pub(super) element: T,
        pub(super) prev: NodePtr<T>,
        pub(super) next: NodePtr<T>,
    }
    impl<T> Node<T> {
        // 注意返回的是多所有权节点
        pub(super) fn new(element: T) -> Rc<RefCell<Node<T>>> {
            Rc::new(RefCell::new(Node {
                element,
                prev: None,
                next: None,
            }))
        }
    }
}
pub struct Iter<'a, T>(Option<Ref<'a, Node<T>>>);
pub struct IterMut<'a, T>(Option<RefMut<'a, Node<T>>>);
pub struct IntoIter<T>(DbLinkList<T>);

impl<T> Iterator for IntoIter<T> {
    type Item = T;

    fn next(&mut self) -> Option<Self::Item> {
        self.0.pop_head()
    }
}

impl<T> DoubleEndedIterator for IntoIter<T> {
    fn next_back(&mut self) -> Option<Self::Item> {
        self.0.pop_tail()
    }
}

#[test]
pub fn shit_test() {
    let mut list = DbLinkList::new();
    list.push_head(1);
    list.push_head(2);
    println!("{:?}", list.peek_head());
    println!("{:?}", list.peek_tail());
    list.push_tail(3);
    println!("{:?}", list.peek_tail());

    // let i = list.pop_head().unwrap();
    // println!("{}", i);
    // let i = list.pop_tail().unwrap();
    // println!("{}", i);
    for x in list.into_iter() {
        println!("{x}");
    }

    // let rc_node = Node::new(1);
    // println!("rc1_cnt: {}", Rc::strong_count(&rc_node));
    //
    // let rc_node2 = Node::new(2);
    // println!("rc2_cnt: {}", Rc::strong_count(&rc_node2));
    // rc_node.borrow_mut().next = Some(rc_node2.clone());
    // println!("rc2_cnt: {}", Rc::strong_count(&rc_node2));
    //
    // // rc_node.borrow_mut().next = None;
    // let option = rc_node.borrow_mut().next.take();
    // println!("rc2_cnt: {}", Rc::strong_count(&rc_node2));
}
